package routers

import (
	"encoding/json"
	"fmt"
	"net/http"
	"strconv"
	"strings"

	jwt "github.com/dgrijalva/jwt-go"
	"github.com/labstack/echo"
	"shqsoft.cn/pas3ui/base"
	"shqsoft.cn/pas3ui/entity"
	"shqsoft.cn/pas3ui/workflow"
	work "shqsoft.cn/pas3ui/workflow/entity"
)

// FolwCreate 路由：流程创建
func FolwCreate(c echo.Context) error {
	wfidStr := c.Param("wfid")
	wfid, err := strconv.Atoi(wfidStr)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "wfid不能为空，且必须为Int！")
	}
	userIDStr := c.FormValue("userID")
	userID, err := strconv.Atoi(userIDStr)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "userID不能为空，且必须为Int！")
	}
	runID, err := workflow.Create(wfid, userID, nil)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	lc := fmt.Sprintf("创建流程:%d", runID)
	base.LogToDB(userID, 200, lc, c.RealIP())
	return c.String(http.StatusOK, fmt.Sprintf(`{"runID":%d}`, runID))
}

// FolwSubmit 路由：流程提交
func FolwSubmit(c echo.Context) error {
	runIDStr := c.Param("runID")
	runID, err := strconv.Atoi(runIDStr)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "runID不能为空，且必须为Int！")
	}
	userIDStr := c.FormValue("userID")
	userID, err := strconv.Atoi(userIDStr)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "userID不能为空，且必须为Int！")
	}
	desc := c.FormValue("desc")
	bType := c.FormValue("bType")
	var subType string
	if bType == "agree" {
		subType = "1"
	} else {
		subType = "4"
	}
	if err := workflow.Submit(runID, userID, desc, subType); err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	lc := fmt.Sprintf("流程提交:%d", runID)
	base.LogToDB(userID, 200, lc, c.RealIP())
	return c.JSON(http.StatusOK, "OK")
}

func FolwSubmitBatch(c echo.Context) error {
	runIDStr := c.FormValue("runIDs")
	var runIDs []int
	err := json.Unmarshal([]byte(runIDStr), &runIDs)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "runIDs必须是int类型的数组！")
	}
	userIDStr := c.FormValue("userID")
	userID, err := strconv.Atoi(userIDStr)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "userID必须是int类型！")
	}
	desc := c.FormValue("desc")
	bType := c.FormValue("bType")
	var subType string
	if bType == "agree" || bType == "" {
		subType = "1"
	} else {
		subType = "4"
	}
	tx := base.MYDB.Begin()
	for _, runID := range runIDs {
		if err = workflow.SubmitWithTX(runID, userID, desc, subType, tx); err != nil {
			tx.Rollback()
			lc := fmt.Sprintf("流程提交:%d", runID)
			base.LogToDB(userID, 200, lc, c.RealIP())
			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
		}
	}
	tx.Commit()
	// var (
	// 	uid  int
	// 	cunm string
	// 	mail string
	// )
	// var selStr string
	// if base.AppConf.Database.Mysql != "" {
	// 	selStr = "UID,GROUP_CONCAT(CUNM) CUNM"
	// } else {
	// 	selStr = `"UID",string_agg("CUNM",',') "CUNM"`
	// }
	// daoName := c.Param("DaoName")
	// if daoName == "" {
	// 	return echo.NewHTTPError(http.StatusBadRequest, "daoName不能为空！")
	// }
	// if strings.HasSuffix(daoName, "App") {
	// 	return c.JSON(http.StatusOK, "OK")
	// }
	// dao, err := base.GetDao(daoName + "AppHis")
	// if err != nil {
	// 	return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	// }
	// ent := dao.GetEntity()
	// rows, err := base.MYDB.Model(ent).Select(selStr).Where(`"FRID" in (select "ID" from "T_FLOW_RUN_HIS" where "STATE"='1' and "ID" in (?))`, runIDs).Group("UID").Rows()
	// if err != nil {
	// 	return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	// }
	// defer rows.Close()
	// subject := "考核系统提示:认定关系审批通过"
	// for rows.Next() {
	// 	err = rows.Scan(&uid, &cunm)
	// 	if err != nil {
	// 		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	// 	}
	// 	err = base.MYDB.Model(entity.User{}).Select(`"EMail"`).Where(`"ID"=?`, uid).Scan(&mail).Error
	// 	if err != nil {
	// 		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	// 	}
	// 	body := "您的申请客户:" + cunm + "认定关系审批通过！"
	// 	if mail != "" {
	// 		err = SendMail([]string{mail}, subject, body)
	// 		if err != nil {
	// 			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	// 		}
	// 	}
	// }
	return c.JSON(http.StatusOK, "OK")
}

// FolwAbort 路由：流程中止
func FolwAbort(c echo.Context) error {
	runIDStr := c.FormValue("runIDs")
	var runIDs []int
	err := json.Unmarshal([]byte(runIDStr), &runIDs)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "runIDs必须是int类型的数组！")
	}
	daoName := c.Param("DaoName")
	if daoName == "" {
		return echo.NewHTTPError(http.StatusBadRequest, "daoName不能为空！")
	}
	dao, err := base.GetDao(daoName)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	ent := dao.GetEntity()
	user := c.Get("user").(*jwt.Token)
	claims := user.Claims.(*UserLoginClaims)
	tx := base.MYDB.Begin()
	for _, runID := range runIDs {
		if err := workflow.AbortWithTx(runID, claims.UserID, tx); err != nil {
			tx.Rollback()
			lc := fmt.Sprintf("流程:%d中止", runID)
			base.LogToDB(claims.UserID, 200, lc, c.RealIP())
			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
		}
	}
	tx.Commit()
	//发送邮件
	var (
		uid  int
		cunm string
		mail string
	)
	subject := "考核系统提示:认定关系审批中止"
	var selStr string
	if base.AppConf.Database.Mysql != "" {
		selStr = "UID,GROUP_CONCAT(CUNM) CUNM"
	} else {
		selStr = `"UID",string_agg("CUNM",',') "CUNM"`
	}
	rows, err := base.MYDB.Model(ent).Select(selStr).Where(`"FRID" IN (?)`, runIDs).Group("UID").Rows()
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	defer rows.Close()
	for rows.Next() {
		rows.Scan(&uid, &cunm)
		err = base.MYDB.Model(entity.User{}).Select(`"EMail"`).Where(`"ID"=?`, uid).Scan(&mail).Error
		if err != nil {
			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
		}
		body := "您的申请客户:" + cunm + "认定关系审批中止！"
		if mail != "" {
			err = SendMail([]string{mail}, subject, body)
			if err != nil {
				return echo.NewHTTPError(http.StatusBadRequest, err.Error())
			}
		}
	}
	return c.JSON(http.StatusOK, "OK")
}

// FolwActivation 路由：流程激活
func FolwActivation(c echo.Context) error {
	runIDStr := c.FormValue("runIDs")
	var runIDs []int
	err := json.Unmarshal([]byte(runIDStr), &runIDs)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "runIDs必须是int类型的数组！")
	}
	user := c.Get("user").(*jwt.Token)
	claims := user.Claims.(*UserLoginClaims)
	tx := base.MYDB.Begin()
	for _, runID := range runIDs {
		if err := workflow.ActivationWithTx(runID, claims.UserID, tx); err != nil {
			tx.Rollback()
			lc := fmt.Sprintf("流程:%d激活", runID)
			base.LogToDB(claims.UserID, 200, lc, c.RealIP())
			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
		}
	}
	tx.Commit()
	return c.JSON(http.StatusOK, "OK")
}

// FolwAbort 路由：流程中止
func FolwDelete(c echo.Context) error {
	runIDStr := c.Param("runID")
	runID, err := strconv.Atoi(runIDStr)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "runID不能为空，且必须为Int！")
	}
	if err := workflow.Delete(runID); err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	return c.JSON(http.StatusOK, "OK")
}

// FolwSendBack 路由：流程退回
func FolwSendBack(c echo.Context) error {
	runIDStr := c.Param("runID")
	runID, err := strconv.Atoi(runIDStr)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "runID不能为空，且必须为Int！")
	}
	userIDStr := c.FormValue("userID")
	userID, err := strconv.Atoi(userIDStr)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "userID不能为空，且必须为Int！")
	}
	backStepIDStr := c.FormValue("backStepID")
	backStepID, err := strconv.Atoi(backStepIDStr)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "backStepID不能为空，且必须为Int！")
	}
	desc := c.FormValue("desc")
	if err := workflow.SendBack(runID, userID, backStepID, desc); err != nil {
		lc := fmt.Sprintf("流程:%d退回", runID)
		base.LogToDB(userID, 200, lc, c.RealIP())
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	return c.JSON(http.StatusOK, "OK")
}

// GetFolwExecutor 路由：获取流程执行人
func GetFolwExecutor(c echo.Context) error {
	runIDStr := c.Param("runID")
	runID, err := strconv.Atoi(runIDStr)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "runID不能为空，且必须为Int！")
	}
	userIDs, _, err := workflow.GetExecutor(runID)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	userMap := make(map[int]string, len(userIDs))
	cache := base.GetEmployeeCache()
	for _, uid := range userIDs {
		userName, err := cache.GetNameByID(uid)
		if err != nil {
			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
		}
		orgName, err := cache.GetDeptNameByID(uid)
		if err != nil {
			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
		}
		userMap[uid] = fmt.Sprintf("%s(%s)", userName, orgName)
	}
	return c.JSON(http.StatusOK, userMap)
}

// GetFolwRunInfo 路由：获取流程运行
func GetFolwRunInfo(c echo.Context) error {
	daoName := c.Param("DaoName")
	if daoName == "" {
		return echo.NewHTTPError(http.StatusBadRequest, "daoName不能为空！")
	}
	runIDStr := c.Param("runID")
	runID, err := strconv.Atoi(runIDStr)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "runID不能为空，且必须为Int！")
	}
	runInfo, err := workflow.GetRunInfo(daoName, runID)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	return c.JSON(http.StatusOK, runInfo)
}

// SetFolwExecutor 路由：设置流程执行人
func SetFolwExecutor(c echo.Context) error {
	runIDStr := c.Param("runID")
	runID, err := strconv.Atoi(runIDStr)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "runID不能为空，且必须为Int！")
	}
	stepIDStr := c.FormValue("stepID")
	stepID, err := strconv.Atoi(stepIDStr)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "stepID不能为空，且必须为Int！")
	}
	userIDarr := strings.Split(c.FormValue("userIDstr"), ",")
	userIDs := make([]int, len(userIDarr))
	for i, uidStr := range userIDarr {
		uid, err := strconv.Atoi(uidStr)
		if err != nil {
			return echo.NewHTTPError(http.StatusBadRequest, "userIDstr不能为空，多个值逗号隔开，且必须为Int！")
		}
		userIDs[i] = uid
	}
	if err := workflow.SetExecutor(runID, stepID, userIDs); err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	return c.JSON(http.StatusOK, "OK")
}
func WorkFlowCompRouter(c echo.Context) error {
	workflow := base.WFContext.GetWorkFlow("compworkflow")
	return c.JSON(http.StatusOK, workflow.Actions)
}
func WorkFlowIndiRouter(c echo.Context) error {
	workflow := base.WFContext.GetWorkFlow("indiworkflow")
	return c.JSON(http.StatusOK, workflow.Actions)
}

func IsManagerRouter(c echo.Context) error {
	permIDStr := c.Param("permID")
	permID, err := strconv.Atoi(permIDStr)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "permID不能为空，且必须为Int！")
	}
	user := c.Get("user").(*jwt.Token)
	claims := user.Claims.(*UserLoginClaims)
	return c.JSON(http.StatusOK, workflow.IsManager(permID, claims.UserID))
}

// GetCompIsDiviRouter 查询对公是否认定
func GetCompIsDiviRouter(c echo.Context) error {
	cunm := c.FormValue("cunm")
	divi := c.FormValue("divi")
	tx := base.MYDB.Begin()
	var isdivi string
	rows, err := tx.Raw("SELECT dbo.GetCompIsDivi(?,?)", cunm, divi).Rows()
	for rows.Next() {
		rows.Scan(&isdivi)
	}
	if err != nil {
		tx.Rollback()
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	tx.Commit()
	return c.JSON(http.StatusOK, isdivi)
}

// GetIndiIsDiviRouter 查询零售是否认定
func GetIndiIsDiviRouter(c echo.Context) error {
	zjhm := c.FormValue("zjhm")
	tx := base.MYDB.Begin()
	var isdivi string
	rows, err := tx.Raw("SELECT [dbo].[GetIndiIsDivi](?)", zjhm).Rows()
	for rows.Next() {
		rows.Scan(&isdivi)
	}
	if err != nil {
		tx.Rollback()
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	tx.Commit()
	return c.JSON(http.StatusOK, isdivi)
}

// 批量删除申请流程
func WorkFlowDeletesRouter(c echo.Context) error {
	var pkVal []interface{}
	jsonStr := c.FormValue("PrimaryKeyValues")
	err := json.Unmarshal([]byte(jsonStr), &pkVal)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	daoName := c.Param("DaoName")
	if daoName == "" {
		return echo.NewHTTPError(http.StatusBadRequest, "daoName不能为空！")
	}
	dao, err := base.GetDao(daoName)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	tx := base.MYDB.Begin()
	ent := dao.GetEntity()
	err = tx.Delete(ent, `"FRID" IN(?)`, pkVal).Error
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	err = tx.Delete(work.FlowRun{}, `"ID" IN(?)`, pkVal).Error
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	err = tx.Delete(work.FlowRunStep{}, `"RUNID" IN(?)`, pkVal).Error
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	tx.Commit()
	return c.JSON(http.StatusOK, "OK")
}
